package com.yesido.spring.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author yesido
 * @description 匹配controller，并且在方法中判断是否用了自定义注解
 * @date 2023-06-24 22:27
 * @Version 8.3
 */
@Aspect
@Component
public class ControllerAspect {
    @Before("execution(* com.yesido.spring.aop.controller.*.*(..))")
    public void checkIdempotent(JoinPoint joinPoint) throws Exception {
        // 获取目标方法的反射信息
        Method targetMethod = getTargetMethod(joinPoint);

        // 判断方法上是否标注了@Idempotent注解
        // 还有的方法就是 在aop中直接监听这个注解 @Before("@annotation(com.yesido.spring.aop.Idempotent)")
        if (targetMethod.isAnnotationPresent(Idempotent.class)) {
            // 执行幂等性检查逻辑
            // ...
        }
    }

    private Method getTargetMethod(JoinPoint joinPoint) throws NoSuchMethodException {
        // 获取目标类的类型
        Class<?> targetClass = joinPoint.getTarget().getClass();

        // 获取方法名
        String methodName = joinPoint.getSignature().getName();

        // 获取方法参数类型列表
        Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();

        // 根据类、方法名和方法参数类型获取目标方法的反射信息
        return targetClass.getMethod(methodName, parameterTypes);
    }
}
